/*
 * @Description: enter your description
 * @Autor: 帅ZR帅
 * @Date: 2023-10-10 19:51:55
 * @LastEditors: 帅ZR帅
 * @LastEditTime: 2023-11-23 22:02:20
 */
#include "IR.h"
// #include <IRremoteESP8266.h>
// #include <IRsend.h>
// #include <IRrecv.h>
// #include <ir_Samsung.h>
//***************************************红外模块**************************************************//
int LASER_OUT = 21; // 激光使能 高电平有效(输出)
int IR_OUT = 4;     // 红外发送使能 高电平有效(输出)
int IR_IN = 5;      // 红外接收 (输入)
//***************************************红外模块**************************************************//

hw_timer_t *tim1 = NULL;
TaskHandle_t GPIO_Handle;
int64_t uart_delay_flag = 0;
uint8_t IR_Send_Finish_flag = 0;
char IR_Data[50];
uint8_t IR_Data_i = 0;
uint8_t IR_ID_645[16] = {0XFE, 0XFE, 0XFE, 0XFE, 0X68, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0X68, 0X13, 0X00, 0XDF, 0X16};
uint8_t IR_ID_698[29] = {0XFE, 0XFE, 0XFE, 0XFE, 0X68, 0X17, 0X00, 0X43, 0X45, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0XAA, 0X01, 0XD2, 0X5E, 0X05, 0X01, 0X01, 0X40, 0X01, 0X02, 0X00, 0X00, 0XC6, 0X07, 0X16};

void tim1Interrupt(void)
{
    uart_delay_flag--;
}
void uart_delay(int64_t us)
{
    uart_delay_flag = us;
    timerWrite(tim1, 0);
    timerAlarmEnable(tim1);
    while (uart_delay_flag > 0)
    {
        NOP();
    }
    timerAlarmDisable(tim1);
}

// void soft_uart_send(uint8_t tx_data)
// {
//   // int64_t us_sbit = 5;  // 波特率4800;
//   // int64_t us_sbit = 10;//波特率2400;
//   int64_t us_sbit = 20; // 波特率1200;
//   digitalWrite(4, LOW); // 起始位
//   uart_delay(us_sbit);
//   /////////////////////////////////////////
//   digitalWrite(4, tx_data & 0x01); // 数据位
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 1 & 0x01);
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 2 & 0x01);
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 3 & 0x01);
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 4 & 0x01);
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 5 & 0x01);
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 6 & 0x01);
//   uart_delay(us_sbit);
//   digitalWrite(4, tx_data >> 7 & 0x01);
//   uart_delay(us_sbit);
//   /////////////////////////////////////////
//   digitalWrite(4, HIGH); // 停止位
//   uart_delay(us_sbit);
//   digitalWrite(4, HIGH); // 拉高等待下一次通信
// }

void soft_uart_send(uint8_t tx_data) // 偶校验 9位
{
    // int64_t us_sbit = 5;  // 波特率4800;
    // int64_t us_sbit = 10;//波特率2400;
    int64_t us_sbit = 20; // 波特率1200;
    uint8_t sum_1 = 0;
    ledcWrite(3, 512);
    digitalWrite(8, 0);
    uart_delay(us_sbit);
    /////////////////////////////////////////
    if (!(tx_data & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 1) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 2) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 3) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 4) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 5) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 6) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    if (!((tx_data >> 7) & 0x01))
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
        sum_1++;
    }
    uart_delay(us_sbit);
    /////////////////////////////////////////偶校验位
    if (sum_1 % 2 == 0)
    {
        ledcWrite(3, 512);
        digitalWrite(8, 0);
    }
    else
    {
        ledcWrite(3, 0);
        digitalWrite(8, 1);
    }
    uart_delay(us_sbit);
    /////////////////////////////////////////停止位
    ledcWrite(3, 0);
    digitalWrite(8, 1);
    uart_delay(us_sbit);
    /////////////////////////////////////////
    ledcWrite(3, 0); // 拉高等待下一次通信
    digitalWrite(8, 1);
}

void soft_uart_receive_start(void)
{
    if (IR_Send_Finish_flag == 1)
    {
        // IR_Send_Finish_flag = 0;
        xTaskResumeFromISR(GPIO_Handle);
    }
}

void soft_uart_receive(void *args)
{
    int64_t us_sbit = 20; // 波特率1200;
    uint8_t receive_bit = 0;
    vTaskSuspend(GPIO_Handle);
    while (1)
    {
        receive_bit = 0;
        uart_delay(25); // 等待起始位结束
        receive_bit = receive_bit | digitalRead(5);
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 1;
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 2;
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 3;
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 4;
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 5;
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 6;
        uart_delay(us_sbit);
        receive_bit = receive_bit | digitalRead(5) << 7;
        uart_delay(us_sbit);
        if (receive_bit == 0x16)
        {
            soft_uart_send(receive_bit);
        }
        if (receive_bit != 0x16)
        {
            IR_Data[IR_Data_i++] = receive_bit;
        }
        else if (IR_Data_i >= 45)
        {
            memset(IR_Data, 0, sizeof(IR_Data));
            IR_Data_i = 0;
        }
        else
        {
            IR_Data[IR_Data_i] = receive_bit;
            IR_Data_i = 0;
            // char *newValue = IR_Data;
            // sprintf(IR_Data, "%d", receive_bit);
            char *newValue = IR_Data;
            pCharacteristic->setValue(newValue);
            pCharacteristic->notify();
            IR_Send_Finish_flag = 2;
        }
        vTaskSuspend(GPIO_Handle);
    }
}
void IR_Scan(void)
{

    int i = 0;
    while (i <= 15)
    {
        soft_uart_send(IR_ID_645[i++]);
    }

    i = 0;
    while (i <= 28)
    {
        soft_uart_send(IR_ID_698[i++]);
    }
}
void IR_645_Scan(void)
{
    if (IR_Flag > 0)
    {
        int i = 0;
        int z = 0;
        int z1 = 0;
        int flag = 0;
        char reveive_data_1[100];
        memset(reveive_data_1, 0, sizeof(reveive_data_1));
        while (UART_CAM.read() >= 0)
            ;
        i = 0;
        while (i <= 15)
        {
            soft_uart_send(IR_ID_645[i++]);
        }
        i = 0;
        // IR_Scan();
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        while (UART_CAM.available())
        {
            char reveive_data[3];
            reveive_data[0] = UART_CAM.read();
            // if (reveive_data[0] == 0)
            // {
            //     reveive_data[0] = 0x01;
            // }
            reveive_data_1[i++] = reveive_data[0];
        }

        // char *newValue = reveive_data_1;
        // pCharacteristic->setValue(newValue);
        // pCharacteristic->notify();
        // 68 70 28 15 00 21 15 68 93 06 a3 5b 48 33 54 48 61 16
        ////////////////////////////////////////////
        if (reveive_data_1[0] == 0x68 || reveive_data_1[0] == 0xfe) //
        {
            char list_IR[100];
            memset(list_IR, 0, sizeof(list_IR));
            int get_flag = 0;
            if (flag == 0)
            {
                for (int j = z1; j < i; j++)
                {
                    if (get_flag != 0 && reveive_data_1[j] != 0xfe) // 跳过 FE 唤醒信号
                    {
                        list_IR[z] = reveive_data_1[j] / 16 + 48 * ID1() + ID0();
                        if (list_IR[z++] > 0x39)
                        {
                            list_IR[z - 1] = list_IR[z - 1] + 7 * ID1() + ID0();
                        }
                        list_IR[z] = reveive_data_1[j] % 16 + 48 * ID1() + ID0();
                        if (list_IR[z++] > 0x39)
                        {
                            list_IR[z - 1] = list_IR[z - 1] + 7 * ID1() + ID0();
                        }
                    }
                    if (get_flag == 0 && reveive_data_1[j] == 0x16)
                    {
                        get_flag = j;
                    }
                    else if (get_flag != 0 && reveive_data_1[j] == 0x68 && z > 3 && reveive_data_1[j - 1] != 0xfe) // 跳过 FE 唤醒信号
                    {
                        get_flag = 0;
                        IR_Flag = 0;
                    }
                }

                memset(scan_data_1, 0, sizeof(scan_data_1));
                memset(scan_data_2, 0, sizeof(scan_data_2));
                char key_1[50];
                char key_2[50];
                memset(key_1, 0, sizeof(key_1));
                memset(key_2, 0, sizeof(key_2));
                char list_IR_00[100];
                list_IR_00[0] = list_IR[12];
                list_IR_00[1] = list_IR[13];
                list_IR_00[2] = list_IR[10];
                list_IR_00[3] = list_IR[11];
                list_IR_00[4] = list_IR[8];
                list_IR_00[5] = list_IR[9];
                list_IR_00[6] = list_IR[6];
                list_IR_00[7] = list_IR[7];
                list_IR_00[8] = list_IR[4];
                list_IR_00[9] = list_IR[5];
                list_IR_00[10] = list_IR[2];
                list_IR_00[11] = list_IR[3];
                memset(list_IR, 0, sizeof(list_IR));
                list_IR[0] = list_IR_00[0];
                list_IR[1] = list_IR_00[1];
                list_IR[2] = list_IR_00[2];
                list_IR[3] = list_IR_00[3];
                list_IR[4] = list_IR_00[4];
                list_IR[5] = list_IR_00[5];
                list_IR[6] = list_IR_00[6];
                list_IR[7] = list_IR_00[7];
                list_IR[8] = list_IR_00[8];
                list_IR[9] = list_IR_00[9];
                list_IR[10] = list_IR_00[10];
                list_IR[11] = list_IR_00[11];
                if (z <= 11)
                {
                    for (int i = 0; i < z; i++)
                    {
                        scan_data_1[i] = list_IR[i];
                        key_1[i] = list_IR[i];
                    }
                    if (IR_Flag == 0)
                    {
                        bleKeyboard.print(key_1);
                    }
                }
                else
                {
                    for (int i = 0; i < 11; i++)
                    {
                        scan_data_1[i] = list_IR[i];
                        key_1[i] = list_IR[i];
                    }
                    for (int i = 11; i < z; i++)
                    {
                        scan_data_2[i - 11] = list_IR[i];
                        key_2[i - 11] = list_IR[i];
                    }
                    if (IR_Flag == 0)
                    {
                        bleKeyboard.print(key_1);
                        vTaskDelay(100 / portTICK_PERIOD_MS);
                        bleKeyboard.print(key_2);
                    }
                }
            }
        }
    }
}
void IR_698_Scan(void)
{
    if (IR_Flag > 0)
    {
        char reveive_data_1[100];
        int i = 0;
        int z = 0;
        int z1 = 0;
        int flag = 0;
        memset(reveive_data_1, 0, sizeof(reveive_data_1));
        while (UART_CAM.read() >= 0)
            ;
        i = 0;
        while (i <= 28)
        {
            soft_uart_send(IR_ID_698[i++]);
        }
        i = 0;
        vTaskDelay(1000 / portTICK_PERIOD_MS);
        while (UART_CAM.available())
        {
            char reveive_data[3];
            reveive_data[0] = UART_CAM.read();
            reveive_data_1[i++] = reveive_data[0];
        }
        if (reveive_data_1[0] == 0x68 || reveive_data_1[0] == 0xfe) //
        {
            char list_IR[100];
            memset(list_IR, 0, sizeof(list_IR));
            int get_flag = 0;
            if (flag == 0)
            {
                for (int j = z1; j < i; j++)
                {
                    if (get_flag != 0 && reveive_data_1[j] != 0xfe) // 跳过 FE 唤醒信号
                    {
                        list_IR[z] = reveive_data_1[j] / 16 + 48;
                        if (list_IR[z++] > 0x39)
                        {
                            list_IR[z - 1] = list_IR[z - 1] + 7 * ID1() + ID0();
                        }
                        list_IR[z] = reveive_data_1[j] % 16 + 48 * ID1() + ID0();
                        if (list_IR[z++] > 0x39)
                        {
                            list_IR[z - 1] = list_IR[z - 1] + 7 * ID1() + ID0();
                        }
                    }
                    if (get_flag == 0 && reveive_data_1[j] == 0x16)
                    {
                        get_flag = j;
                    }
                    else if (get_flag != 0 && reveive_data_1[j] == 0x68 && z > 3 && reveive_data_1[j - 1] != 0xfe)
                    {
                        get_flag = 0;
                        IR_Flag = 0;
                    }
                }
                // pCharacteristic->setValue(newValue);
                // pCharacteristic->notify();

                memset(scan_data_1, 0, sizeof(scan_data_1));
                memset(scan_data_2, 0, sizeof(scan_data_2));
                char key_1[256];
                char key_2[256];
                memset(key_1, 0, sizeof(key_1));
                memset(key_2, 0, sizeof(key_2));

                char list_IR_00[100];
                list_IR_00[0] = list_IR[12];
                list_IR_00[1] = list_IR[13];
                list_IR_00[2] = list_IR[10];
                list_IR_00[3] = list_IR[11];
                list_IR_00[4] = list_IR[8];
                list_IR_00[5] = list_IR[9];
                list_IR_00[6] = list_IR[6];
                list_IR_00[7] = list_IR[7];
                list_IR_00[8] = list_IR[4];
                list_IR_00[9] = list_IR[5];
                list_IR_00[10] = list_IR[2];
                list_IR_00[11] = list_IR[3];
                memset(list_IR, 0, sizeof(list_IR));
                list_IR[0] = list_IR_00[0];
                list_IR[1] = list_IR_00[1];
                list_IR[2] = list_IR_00[2];
                list_IR[3] = list_IR_00[3];
                list_IR[4] = list_IR_00[4];
                list_IR[5] = list_IR_00[5];
                list_IR[6] = list_IR_00[6];
                list_IR[7] = list_IR_00[7];
                list_IR[8] = list_IR_00[8];
                list_IR[9] = list_IR_00[9];
                list_IR[10] = list_IR_00[10];
                list_IR[11] = list_IR_00[11];

                if (z <= 11)
                {
                    for (int i = 0; i < z; i++)
                    {
                        scan_data_1[i] = list_IR[i];
                        key_1[i] = list_IR[i];
                    }
                    if (IR_Flag == 0)
                    {
                        bleKeyboard.print(key_1);
                    }
                }
                else
                {
                    for (int i = 0; i < 11; i++)
                    {
                        scan_data_1[i] = list_IR[i];
                        key_1[i] = list_IR[i];
                    }
                    for (int i = 11; i < z; i++)
                    {
                        scan_data_2[i - 11] = list_IR[i];
                        key_2[i - 11] = list_IR[i];
                    }
                    if (IR_Flag == 0)
                    {
                        bleKeyboard.print(key_1);
                        vTaskDelay(100 / portTICK_PERIOD_MS);
                        bleKeyboard.print(key_2);
                    }
                }
            }
        }
        ////////////////////////////////////////////
    }
}
void IR_Init(void)
{
    ledcSetup(3, 38000, 10);
    ledcAttachPin(IR_OUT, 3);
    ledcWrite(3, 0);

    // 调试脚8 模拟串口TX
    pinMode(8, OUTPUT);
    digitalWrite(8, HIGH);

    // pinMode(4, OUTPUT);
    // digitalWrite(4, HIGH);
    pinMode(14, OUTPUT); // 激光
    digitalWrite(14, HIGH);

    // xTaskCreatePinnedToCore(soft_uart_receive, "soft_uart_receive", 4096, NULL, 6, &GPIO_Handle, 0);
    pinMode(5, INPUT_PULLUP);
    // attachInterrupt(digitalPinToInterrupt(5), soft_uart_receive_start, FALLING);

    tim1 = timerBegin(0, 4, true);
    timerAttachInterrupt(tim1, tim1Interrupt, true);
    timerAlarmWrite(tim1, 833, true);
}